home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / haeberli / libgutil / row.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  14KB  |  776 lines

  1. /*
  2.  * Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. /*
  18.  *    row -
  19.  *        Support for operations on image rows.
  20.  *
  21.  *            Paul Haeberli - 1989
  22.  */
  23. #include "image.h"
  24. #include "lum.h"
  25. #include "math.h"
  26.  
  27. zerorow(sptr,n)
  28. short *sptr;
  29. int n;
  30. {
  31.     bzero(sptr,n*sizeof(short));
  32. }
  33.  
  34. copyrow(s,d,n)
  35. short *s, *d;
  36. int n;
  37. {
  38.     bcopy(s,d,n*sizeof(short));
  39. }
  40.  
  41. setrow(sptr,val,n)
  42. short *sptr;
  43. int val, n;
  44. {
  45.     if(val == 0)
  46.     bzero(sptr,n*sizeof(short));
  47.     else {
  48.      while(n--) 
  49.         *sptr++ = val;
  50.     }
  51. }
  52.  
  53. #define DOCLAMP(iptr)    (((*(iptr) & 0xff00) == 0) ? *(iptr): ((*(iptr)>0) ? 255 : 0))
  54.  
  55. clamprow(iptr,optr,n)
  56. short *iptr, *optr;
  57. int n;
  58. {
  59.     short  val;
  60.  
  61.     while(n>=8) {
  62.     optr[0] = DOCLAMP(iptr+0);
  63.     optr[1] = DOCLAMP(iptr+1);
  64.     optr[2] = DOCLAMP(iptr+2);
  65.     optr[3] = DOCLAMP(iptr+3);
  66.     optr[4] = DOCLAMP(iptr+4);
  67.     optr[5] = DOCLAMP(iptr+5);
  68.     optr[6] = DOCLAMP(iptr+6);
  69.     optr[7] = DOCLAMP(iptr+7);
  70.     iptr += 8;
  71.     optr += 8;
  72.     n -= 8;
  73.     }
  74.     while(n--) {
  75.     optr[0] = DOCLAMP(iptr+0);
  76.     iptr++;
  77.     optr++;
  78.     }
  79. }
  80.  
  81. accrow(iptr,sptr,w,n)
  82. short *iptr;
  83. short *sptr;
  84. int w, n;
  85. {
  86.     if(w == 1) {
  87.     addsrow(iptr,sptr,n);
  88.     } else if(w == -1) {
  89.     subsrow(iptr,sptr,n);
  90.     } else {
  91.     while(n>=8) {
  92.         iptr[0] += w*sptr[0];
  93.         iptr[1] += w*sptr[1];
  94.         iptr[2] += w*sptr[2];
  95.         iptr[3] += w*sptr[3];
  96.         iptr[4] += w*sptr[4];
  97.         iptr[5] += w*sptr[5];
  98.         iptr[6] += w*sptr[6];
  99.         iptr[7] += w*sptr[7];
  100.         iptr += 8;
  101.         sptr += 8;
  102.         n -= 8;
  103.     }
  104.     while(n--) 
  105.         *iptr++ += (w * *sptr++);
  106.     }
  107. }
  108.  
  109. divrow(iptr,optr,tot,n)
  110. short *iptr;
  111. short *optr;
  112. int tot, n;
  113. {
  114.     if(iptr == optr) {
  115.     while(n>=8) {
  116.         optr[0] = optr[0]/tot;
  117.         optr[1] = optr[1]/tot;
  118.         optr[2] = optr[2]/tot;
  119.         optr[3] = optr[3]/tot;
  120.         optr[4] = optr[4]/tot;
  121.         optr[5] = optr[5]/tot;
  122.         optr[6] = optr[6]/tot;
  123.         optr[7] = optr[7]/tot;
  124.         optr += 8;
  125.         n -= 8;
  126.     }
  127.     while(n--) {
  128.         *optr = (*optr)/tot;
  129.         optr++;
  130.     }
  131.     } else {
  132.     while(n>=8) {
  133.         optr[0] = iptr[0]/tot;
  134.         optr[1] = iptr[1]/tot;
  135.         optr[2] = iptr[2]/tot;
  136.         optr[3] = iptr[3]/tot;
  137.         optr[4] = iptr[4]/tot;
  138.         optr[5] = iptr[5]/tot;
  139.         optr[6] = iptr[6]/tot;
  140.         optr[7] = iptr[7]/tot;
  141.         optr += 8;
  142.         iptr += 8;
  143.         n -= 8;
  144.     }
  145.     while(n--) 
  146.         *optr++ = (*iptr++)/tot;
  147.     }
  148. }
  149.  
  150. #define DOTOBW(optr,rptr,gptr,bptr)    *(optr) = ILUM(*(rptr),*(gptr),*(bptr))
  151.  
  152. rgbrowtobw(rbuf,gbuf,bbuf,obuf,n)
  153. unsigned short *rbuf, *gbuf, *bbuf, *obuf;
  154. int n;
  155. {
  156.     while(n>=8) {
  157.     DOTOBW(obuf+0,rbuf+0,gbuf+0,bbuf+0);
  158.     DOTOBW(obuf+1,rbuf+1,gbuf+1,bbuf+1);
  159.     DOTOBW(obuf+2,rbuf+2,gbuf+2,bbuf+2);
  160.     DOTOBW(obuf+3,rbuf+3,gbuf+3,bbuf+3);
  161.     DOTOBW(obuf+4,rbuf+4,gbuf+4,bbuf+4);
  162.     DOTOBW(obuf+5,rbuf+5,gbuf+5,bbuf+5);
  163.     DOTOBW(obuf+6,rbuf+6,gbuf+6,bbuf+6);
  164.     DOTOBW(obuf+7,rbuf+7,gbuf+7,bbuf+7);
  165.     rbuf += 8;
  166.     gbuf += 8;
  167.     bbuf += 8;
  168.     obuf += 8;
  169.     n -= 8;
  170.     } 
  171.     while(n--) {
  172.     DOTOBW(obuf,rbuf,gbuf,bbuf);
  173.     rbuf++;
  174.     gbuf++;
  175.     bbuf++;
  176.     obuf++;
  177.     }
  178. }
  179.  
  180. /*
  181.  *    addsrow -
  182.  *        Add two rows together
  183.  *
  184.  */
  185. addsrow(dptr,sptr,n)
  186. short *dptr, *sptr;
  187. int n;
  188. {
  189.     while(n>=8) {
  190.     dptr[0] += sptr[0];
  191.     dptr[1] += sptr[1];
  192.     dptr[2] += sptr[2];
  193.     dptr[3] += sptr[3];
  194.     dptr[4] += sptr[4];
  195.     dptr[5] += sptr[5];
  196.     dptr[6] += sptr[6];
  197.     dptr[7] += sptr[7];
  198.     dptr += 8;
  199.     sptr += 8;
  200.     n -= 8;
  201.     }
  202.     while(n--) 
  203.     *dptr++ += *sptr++;
  204. }
  205.  
  206. /*
  207.  *    subsrow -
  208.  *        Subtract two rows
  209.  *
  210.  */
  211. subsrow(dptr,sptr,n)
  212. short *dptr, *sptr;
  213. int n;
  214. {
  215.     while(n>=8) {
  216.     dptr[0] -= sptr[0];
  217.     dptr[1] -= sptr[1];
  218.     dptr[2] -= sptr[2];
  219.     dptr[3] -= sptr[3];
  220.     dptr[4] -= sptr[4];
  221.     dptr[5] -= sptr[5];
  222.     dptr[6] -= sptr[6];
  223.     dptr[7] -= sptr[7];
  224.     dptr += 8;
  225.     sptr += 8;
  226.     n -= 8;
  227.     }
  228.     while(n--) 
  229.     *dptr++ -= *sptr++;
  230. }
  231.  
  232. bitstorow(bits,sbuf,n)
  233. unsigned char *bits;
  234. short *sbuf;
  235. int n;
  236. {
  237.     int i, val, nbytes;
  238.  
  239.     nbytes = ((n-1)/8)+1;
  240.     for(i = 0; i<nbytes; i++ ) {
  241.     val = *bits++;
  242.     if(val&0x80)
  243.         sbuf[0] = 0;
  244.     else
  245.         sbuf[0] = 255;
  246.     if(val&0x40)
  247.         sbuf[1] = 0;
  248.     else
  249.         sbuf[1] = 255;
  250.     if(val&0x20)
  251.         sbuf[2] = 0;
  252.     else
  253.         sbuf[2] = 255;
  254.     if(val&0x10)
  255.         sbuf[3] = 0;
  256.     else
  257.         sbuf[3] = 255;
  258.     if(val&0x08)
  259.         sbuf[4] = 0;
  260.     else
  261.         sbuf[4] = 255;
  262.     if(val&0x04)
  263.         sbuf[5] = 0;
  264.     else
  265.         sbuf[5] = 255;
  266.     if(val&0x02)
  267.         sbuf[6] = 0;
  268.     else
  269.         sbuf[6] = 255;
  270.     if(val&0x01)
  271.         sbuf[7] = 0;
  272.     else
  273.         sbuf[7] = 255;
  274.     sbuf += 8;
  275.     }
  276. }
  277.  
  278. rowtobits(sbuf,bits,n)
  279. short *sbuf;
  280. unsigned char *bits;
  281. int n;
  282. {
  283.     int i, val, nbytes, thresh;
  284.  
  285.     nbytes = ((n-1)/8)+1;
  286.     thresh = 128;
  287.     for(i = 0; i<nbytes; i++) {
  288.     val = 0;
  289.     if(sbuf[0]<thresh)
  290.         val |= 0x80;
  291.     if(sbuf[1]<thresh)
  292.         val |= 0x40;
  293.     if(sbuf[2]<thresh)
  294.         val |= 0x20;
  295.     if(sbuf[3]<thresh)
  296.         val |= 0x10;
  297.     if(sbuf[4]<thresh)
  298.         val |= 0x08;
  299.     if(sbuf[5]<thresh)
  300.         val |= 0x04;
  301.     if(sbuf[6]<thresh)
  302.         val |= 0x02;
  303.     if(sbuf[7]<thresh)
  304.         val |= 0x01;
  305.     sbuf += 8;
  306.     *bits++ = val;
  307.     }
  308. }
  309.  
  310. /* 
  311.  *    bit reverse a stream of bytes
  312.  *
  313.  */
  314. bitrevbytes(buf,n)
  315. unsigned char *buf;
  316. int n;
  317. {
  318.     int i, x, br;
  319.     static unsigned char *bitrev;
  320.  
  321.     if(!bitrev) {
  322.     bitrev = (unsigned char *)mymalloc(256);
  323.     for(i=0; i<256; i++) {
  324.         br = 0;
  325.         for(x=0; x<8; x++) {
  326.         br = br<<1;
  327.         if(i&(1<<x))
  328.             br |= 1;
  329.         }
  330.         bitrev[i] = br;
  331.     }
  332.     }
  333.     while(n>=8) {
  334.     buf[0] = bitrev[buf[0]];
  335.     buf[1] = bitrev[buf[1]];
  336.     buf[2] = bitrev[buf[2]];
  337.     buf[3] = bitrev[buf[3]];
  338.     buf[4] = bitrev[buf[4]];
  339.     buf[5] = bitrev[buf[5]];
  340.     buf[6] = bitrev[buf[6]];
  341.     buf[7] = bitrev[buf[7]];
  342.     buf += 8;
  343.     n -= 8;
  344.     }
  345.     while(n--) {
  346.     buf[0] = bitrev[buf[0]];
  347.     *buf++;
  348.     }
  349. }
  350.  
  351. /* 
  352.  *    flip a row of shorts
  353.  *
  354.  */
  355. flipsrow(sptr,n) 
  356. short *sptr;
  357. int n;
  358. {
  359.     short temp, *p1, *p2;
  360.  
  361.     p1 = sptr;
  362.     p2 = sptr+n-1;
  363.     n = n/2;
  364.     while(n--) {
  365.     temp = *p1;
  366.     *p1++ = *p2;
  367.     *p2-- = temp;
  368.     }
  369. }
  370.  
  371. /*     cpack -
  372.  *        Convert from and to cpack format.
  373.  *    
  374.  */
  375. bwtocpack(b,l,n)
  376. unsigned short *b;
  377. unsigned long *l;
  378. int n;
  379. {
  380.     while(n>=8) {
  381.     l[0] = 0xff000000+0x00010101*b[0];
  382.     l[1] = 0xff000000+0x00010101*b[1];
  383.     l[2] = 0xff000000+0x00010101*b[2];
  384.     l[3] = 0xff000000+0x00010101*b[3];
  385.     l[4] = 0xff000000+0x00010101*b[4];
  386.     l[5] = 0xff000000+0x00010101*b[5];
  387.     l[6] = 0xff000000+0x00010101*b[6];
  388.     l[7] = 0xff000000+0x00010101*b[7];
  389.     l += 8;
  390.     b += 8;
  391.     n -= 8;
  392.     }
  393.     while(n--) 
  394.     *l++ = 0xff000000+0x00010101*(*b++);
  395. }
  396.  
  397. rgbtocpack(r,g,b,l,n)
  398. unsigned short *r, *g, *b;
  399. unsigned long *l;
  400. int n;
  401. {
  402.     while(n>=8) {
  403.     l[0] = r[0] | (g[0]<<8) | (b[0]<<16) | (0xff<<24);
  404.     l[1] = r[1] | (g[1]<<8) | (b[1]<<16) | (0xff<<24);
  405.     l[2] = r[2] | (g[2]<<8) | (b[2]<<16) | (0xff<<24);
  406.     l[3] = r[3] | (g[3]<<8) | (b[3]<<16) | (0xff<<24);
  407.     l[4] = r[4] | (g[4]<<8) | (b[4]<<16) | (0xff<<24);
  408.     l[5] = r[5] | (g[5]<<8) | (b[5]<<16) | (0xff<<24);
  409.     l[6] = r[6] | (g[6]<<8) | (b[6]<<16) | (0xff<<24);
  410.     l[7] = r[7] | (g[7]<<8) | (b[7]<<16) | (0xff<<24);
  411.     l += 8;
  412.     r += 8;
  413.     g += 8;
  414.     b += 8;
  415.     n -= 8;
  416.     }
  417.     while(n--) 
  418.         *l++ = *r++ | ((*g++)<<8) | ((*b++)<<16) | (0xff<<24);
  419. }
  420.  
  421. rgbatocpack(r,g,b,a,l,n)
  422. unsigned short *r, *g, *b, *a;
  423. unsigned long *l;
  424. int n;
  425. {
  426.     while(n>=8) {
  427.     l[0] = r[0] | (g[0]<<8) | (b[0]<<16) | (a[0]<<24);
  428.     l[1] = r[1] | (g[1]<<8) | (b[1]<<16) | (a[1]<<24);
  429.     l[2] = r[2] | (g[2]<<8) | (b[2]<<16) | (a[2]<<24);
  430.     l[3] = r[3] | (g[3]<<8) | (b[3]<<16) | (a[3]<<24);
  431.     l[4] = r[4] | (g[4]<<8) | (b[4]<<16) | (a[4]<<24);
  432.     l[5] = r[5] | (g[5]<<8) | (b[5]<<16) | (a[5]<<24);
  433.     l[6] = r[6] | (g[6]<<8) | (b[6]<<16) | (a[6]<<24);
  434.     l[7] = r[7] | (g[7]<<8) | (b[7]<<16) | (a[7]<<24);
  435.     l += 8;
  436.     r += 8;
  437.     g += 8;
  438.     b += 8;
  439.     a += 8;
  440.     n -= 8;
  441.     }
  442.     while(n--) 
  443.         *l++ = *r++ | ((*g++)<<8) | ((*b++)<<16) | ((*a++)<<24);
  444. }
  445.  
  446. #define CPACKTORGB(l,r,g,b)            \
  447.     val = (l);                \
  448.     (r) = (val>>0) & 0xff;            \
  449.     (g) = (val>>8) & 0xff;            \
  450.     (b) = (val>>16) & 0xff;            
  451.  
  452. cpacktorgb(l,r,g,b,n)
  453. unsigned long *l;
  454. unsigned short *r, *g, *b;
  455. int n;
  456. {
  457.     unsigned long val;
  458.  
  459.     while(n>=8) {
  460.     CPACKTORGB(l[0],r[0],g[0],b[0]);
  461.     CPACKTORGB(l[1],r[1],g[1],b[1]);
  462.     CPACKTORGB(l[2],r[2],g[2],b[2]);
  463.     CPACKTORGB(l[3],r[3],g[3],b[3]);
  464.     CPACKTORGB(l[4],r[4],g[4],b[4]);
  465.     CPACKTORGB(l[5],r[5],g[5],b[5]);
  466.     CPACKTORGB(l[6],r[6],g[6],b[6]);
  467.     CPACKTORGB(l[7],r[7],g[7],b[7]);
  468.     l += 8;
  469.     r += 8;
  470.     g += 8;
  471.     b += 8;
  472.     n -= 8;
  473.     }
  474.     while(n--) {
  475.     CPACKTORGB(l[0],r[0],g[0],b[0]);
  476.     l++;
  477.     r++;
  478.     g++;
  479.     b++;
  480.     }
  481. }
  482.  
  483. #define CPACKTORGBA(l,r,g,b,a)            \
  484.     val = (l);                \
  485.     (r) = (val>>0) & 0xff;            \
  486.     (g) = (val>>8) & 0xff;            \
  487.     (b) = (val>>16) & 0xff;            \
  488.     (a) = (val>>24) & 0xff;            
  489.  
  490. cpacktorgba(l,r,g,b,a,n)
  491. unsigned long *l;
  492. unsigned short *r, *g, *b, *a;
  493. int n;
  494. {
  495.     unsigned long val;
  496.  
  497.     while(n>=8) {
  498.     CPACKTORGBA(l[0],r[0],g[0],b[0],a[0]);
  499.     CPACKTORGBA(l[1],r[1],g[1],b[1],a[1]);
  500.     CPACKTORGBA(l[2],r[2],g[2],b[2],a[2]);
  501.     CPACKTORGBA(l[3],r[3],g[3],b[3],a[3]);
  502.     CPACKTORGBA(l[4],r[4],g[4],b[4],a[4]);
  503.     CPACKTORGBA(l[5],r[5],g[5],b[5],a[5]);
  504.     CPACKTORGBA(l[6],r[6],g[6],b[6],a[6]);
  505.     CPACKTORGBA(l[7],r[7],g[7],b[7],a[7]);
  506.     l += 8;
  507.     r += 8;
  508.     g += 8;
  509.     b += 8;
  510.     a += 8;
  511.     n -= 8;
  512.     }
  513.     while(n--) {
  514.     CPACKTORGBA(l[0],r[0],g[0],b[0],a[0]);
  515.     l++;
  516.     r++;
  517.     g++;
  518.     b++;
  519.     a++;
  520.     }
  521. }
  522.  
  523. /*
  524.  *    normrow -
  525.  *        Normalize a row of image data
  526.  *
  527.  */
  528. normrow(image,buf)
  529. IMAGE *image;
  530. short *buf;
  531. {
  532.     int n, max;
  533.  
  534.     n = image->xsize;
  535.     max = image->max;
  536.     if(max == 255 || max == 0)
  537.     return;
  538.     while(n>=8) {
  539.     buf[0] = (buf[0]*255)/max;
  540.     buf[1] = (buf[1]*255)/max;
  541.     buf[2] = (buf[2]*255)/max;
  542.     buf[3] = (buf[3]*255)/max;
  543.     buf[4] = (buf[4]*255)/max;
  544.     buf[5] = (buf[5]*255)/max;
  545.     buf[6] = (buf[6]*255)/max;
  546.     buf[7] = (buf[7]*255)/max;
  547.     buf += 8;
  548.     n -= 8;
  549.     }
  550.     while(n--) {
  551.     *buf = (*buf*255)/max;
  552.     buf++;
  553.     }
  554. }
  555.  
  556. static short *rbuf, *gbuf, *bbuf;
  557. static int malloclen = 0;
  558.  
  559. int getbwrow(image,buf,y)
  560. IMAGE *image;
  561. char *buf;
  562. int y;
  563. {
  564.     int retval; 
  565.  
  566.     if(malloclen<image->xsize) {
  567.     if(malloclen) {
  568.         free(rbuf);
  569.         free(gbuf);
  570.         free(bbuf);
  571.     }
  572.     rbuf = (short *)mymalloc(image->xsize*sizeof(short));
  573.     gbuf = (short *)mymalloc(image->xsize*sizeof(short));
  574.     bbuf = (short *)mymalloc(image->xsize*sizeof(short));
  575.     malloclen=image->xsize;;
  576.     }
  577.     if(image->zsize<3) {
  578.     retval = getrow(image,buf,y,0);
  579.     } else {
  580.     getrow(image,rbuf,y,0);
  581.     getrow(image,gbuf,y,1);
  582.     retval = getrow(image,bbuf,y,2);
  583.     rgbrowtobw(rbuf,gbuf,bbuf,buf,image->xsize);
  584.     }
  585.     return retval;
  586. }
  587.  
  588. putfliprow(image,buf,y,z,flipcode)
  589. IMAGE *image;
  590. short *buf;
  591. int y, z;
  592. int flipcode;
  593. {
  594.     if(flipcode&1)
  595.     flipsrow(buf,image->xsize);
  596.     if(flipcode&2)
  597.     putrow(image,buf,(image->ysize-1)-y,z);
  598.     else
  599.     putrow(image,buf,y,z);
  600. }
  601.  
  602. int getfliprow(image,buf,y,z,flipcode)
  603. IMAGE *image;
  604. short *buf;
  605. int y, z, flipcode;
  606. {
  607.     int retval; 
  608.  
  609.     if(flipcode&2)
  610.     retval = getrow(image,buf,(image->ysize-1)-y,z);
  611.     else
  612.     retval = getrow(image,buf,y,z);
  613.     if(flipcode&1)
  614.     flipsrow(buf,image->xsize);
  615.     return retval;
  616. }
  617.  
  618. static float curgamma = -1.0;
  619. static short *cortab;
  620.  
  621. int getgamrow(image,buf,y,z,gamval)
  622. IMAGE *image;
  623. short *buf;
  624. int y, z;
  625. float gamval;
  626. {
  627.     int i, retval;
  628.     float delta;
  629.  
  630.     retval = getrow(image,buf,y,z);
  631.     if(gamval<0.999 || gamval>1.001) {
  632.     delta = curgamma-gamval;
  633.     if(delta<0.0)
  634.         delta = -delta;
  635.     if(delta>0.001) {
  636.         if(!cortab) 
  637.         cortab = (short *)malloc(256*sizeof(short));
  638.         for(i=0; i<256; i++) 
  639.         cortab[i] = (255.0*pow(i/255.0,gamval))+0.499;
  640.         curgamma = gamval;
  641.      }
  642.     applytable(buf,cortab,image->xsize);
  643.     }
  644.     return retval;
  645. }
  646.  
  647. applytable(buf,cortab,n)
  648. short *buf;
  649. short *cortab;
  650. int n;
  651. {
  652.     if(cortab) {
  653.         while(n--) {
  654.             *buf = cortab[*buf];
  655.             buf++;
  656.         }
  657.     }
  658. }
  659.  
  660. /* 
  661.  *    dithering stuff follows
  662.  *
  663.  */
  664. #define MATSIZE88
  665.  
  666. #define XSIZE    8
  667. #define YSIZE    8
  668.  
  669. static short dithmat[YSIZE][XSIZE] = {        /* 8x8 Limb */
  670.     0,    8,    36,    44,    2,    10,    38,    46,
  671.     16,    24,    52,    60,    18,    26,    54,    62,
  672.     32,    40,     4,    12,    34,    42,    6,    14,
  673.     48,    56,    20,    28,    50,    58,    22,    30,
  674.     3,    11,    39,    47,    1,    9,    37,    45,
  675.     19,    27,    55,    63,    17,    25,    53,    61,
  676.     35,    43,    7,    15,    33,    41,    5,    13,
  677.     51,    59,    23,    31,    49,    57,    21,    29,
  678. };
  679.  
  680. #ifdef NOTDEF
  681. static short dithmat[YSIZE][XSIZE] = {        /* halftone dots */
  682.     3,    17,    55,     63,    61,     47,    9,    1,
  683.     15,     29,    39,    51,    49,    35,    25,    13,
  684.     40,    32,    26,    20,    22,    30,    36,    42,
  685.     56,    44,    10,    4,    6,    18,    52,    58,
  686.     60,    46,    8,    0,    2,    16,    54,    62,
  687.     48,    34,    24,    12,    14,    28,    38,    50,
  688.     23,    31,    37,    43,    41,    33,    27,    21,
  689.     7,    19,    53,    59,    57,    45,    11,    5,
  690. };
  691. #endif
  692.  
  693. #define TOTAL        (XSIZE*YSIZE)
  694.  
  695. ditherrow(buf,y,n)
  696. short *buf;
  697. int y, n;
  698. {
  699.     int r, val;
  700.     int rshades, rmaxbits;
  701.     short *rdith, *gdith, *bdith;
  702.  
  703.     rdith = &dithmat[y%YSIZE][0];
  704.     rshades = TOTAL+1;
  705.     rmaxbits = ((rshades-1)/TOTAL);
  706.     while(n--) {
  707.     r = *buf;
  708.     val = (rshades*r)/255;
  709.     if(val>=TOTAL) 
  710.         *buf++ = 255;
  711.     else if(val>rdith[n%XSIZE])
  712.         *buf++ = 255;
  713.     else
  714.         *buf++ = 0;
  715.     }
  716. }
  717.  
  718. tilegetrow(image,buf,y,z,xsize)
  719. IMAGE *image;
  720. short *buf;
  721. int y, z, xsize;
  722. {
  723.     getrow(image,buf,y%image->ysize,z);
  724.     reprow(buf,image->xsize,xsize);
  725. }
  726.  
  727. reprow(buf,isize,osize)
  728. short *buf;
  729. int isize, osize;
  730. {
  731.     short *iptr, *optr;
  732.     int n, togo;
  733.  
  734.     optr = buf+isize;
  735.     togo = osize-isize;
  736.     while (togo>0) {
  737.     if (togo>isize) 
  738.         n = isize;
  739.     else
  740.         n = togo; 
  741.      iptr = buf;
  742.     togo -= n;
  743.     while(n--) 
  744.         *optr++ = *iptr++;
  745.     }
  746. }
  747.  
  748. static unsigned char *bitcount;
  749.  
  750. int countbits(buf,n)
  751. unsigned char *buf;
  752. int n;
  753. {
  754.     unsigned int i, c;
  755.  
  756.     if(!bitcount) {
  757.     bitcount = (unsigned char *)malloc(256);
  758.     for(i=0; i<256; i++) {
  759.         c = 0;
  760.         if(i&0x01) c++;
  761.         if(i&0x02) c++;
  762.         if(i&0x04) c++;
  763.         if(i&0x08) c++;
  764.         if(i&0x10) c++;
  765.         if(i&0x20) c++;
  766.         if(i&0x40) c++;
  767.         if(i&0x80) c++;
  768.         bitcount[i] = c;
  769.     }
  770.     }
  771.     c = 0;
  772.     while(n--) 
  773.     c += bitcount[*buf++];
  774.     return c;
  775. }
  776.